package cn.virens.dd;

import java.util.Collection;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.virens.common.utils.Assert;
import cn.virens.dd.execute.ExecuteWorkStrategy;
import cn.virens.dd.execute.ExecuteWorkStrategyTasks;
import cn.virens.dd.stack.StrategyStack;
import cn.virens.dd.stack.StrategyValueStack;

public class StrategyManageImpl implements StrategyManage, AutoCloseable {
	private static final Logger logger = LoggerFactory.getLogger(StrategyManageImpl.class);

	private final StrategyStack strategyStack = new StrategyStack();
	private final StrategyValueStack valueStack = new StrategyValueStack();

	private final ExecuteWorkStrategy executor1 = new ExecuteWorkStrategy(100, 10);
	private final ExecuteWorkStrategyTasks executor2 = new ExecuteWorkStrategyTasks(100, 10);

	@Override
	public StrategyValue getValue(Strategy strategy) {
		return getValue(strategy.getClass());
	}

	@Override
	public StrategyValue getValue(Class<? extends Strategy> clazz) {
		return clazz != null ? valueStack.get(clazz) : null;
	}

	@Override
	public boolean putValue(Class<? extends Strategy> clazz, StrategyValue value) {
		return value != null && this.valueStack.put(clazz, value) == null;
	}

	@Override
	public boolean putStrategy(String uid, Strategy strategy) {
		return strategyStack.put(uid, strategy) == null;
	}

	@Override
	public boolean putTask(String strategyUid, String uid, StrategyTask task) {
		Strategy strategy = strategyStack.get(Assert.isEmpty(strategyUid));
		if (strategy != null && uid != null && task != null) {
			return strategy.putTask(uid, task);
		} else {
			return false;
		}
	}

	@Override
	public void executeStrategyStack() {
		Collection<Strategy> stack = strategyStack.values();
		List<Exception> result = executor1.execute(this, stack);

		// 检查所有的执行结果，并将失败的记录打印出来
		for (int i = 0; i < result.size(); i++) {
			logger.error("执行异常：", result.get(i));
		}
	}

	public ExecuteWorkStrategy getExecutor1() {
		return executor1;
	}

	public ExecuteWorkStrategyTasks getExecutor2() {
		return executor2;
	}

	@Override
	public void close() throws Exception {
		this.executor2.close();
		this.executor1.close();
	}
}
